package grpc

import (
	"base_server/internal/models/cutpart"
	"base_server/internal/models/fashion"
	"base_server/internal/services"
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/parnurzeal/gorequest"
	common "jihe.common"
	"jihe.common/oss"
	"jihe.common/protos/base_server/proto"
)

func (s *Server) BaseGetAlgorithmConfig(ctx context.Context, req *proto.BaseGetAlgorithmConfigReq) (ret *proto.BaseAlgorithmConfig, err error) {
	ret = new(proto.BaseAlgorithmConfig)
	redisClient := s.Redis.Get()
	configData, e := redisClient.Get(s.Redis.GetBaseAlgorithmConfigKey()).Bytes()
	if e == nil {
		e = json.Unmarshal(configData, ret)
		if e == nil {
			return
		}
	}
	configUrl := fmt.Sprintf("%s/%s_config.json?%d", s.Conf.Get().Oss.Domain, s.Conf.Get().Runmode, time.Now().UnixNano())
	_, body, errs := gorequest.New().Get(configUrl).Timeout(time.Second * 10).EndStruct(ret)
	if len(errs) != 0 {
		err = errs[0]
		return
	}
	redisClient.Set(s.Redis.GetBaseAlgorithmConfigKey(), string(body), -1)
	return
}

func (s *Server) BaseUpdateAlgorithmConfig(ctx context.Context, req *proto.BaseAlgorithmConfig) (ret *proto.BaseUpdateAlgorithmConfigRes, err error) {
	ret = new(proto.BaseUpdateAlgorithmConfigRes)
	bucket, err := oss.GetClient().Bucket("jihe-file")
	if err != nil {
		return
	}
	jsonByte, err := json.Marshal(req)
	if err != nil {
		return
	}
	err = s.Redis.Get().Set(s.Redis.GetBaseAlgorithmConfigKey(), string(jsonByte), -1).Err()
	if err == nil {
		_ = bucket.PutObject(fmt.Sprintf("%s_config.json", s.Conf.Get().Runmode), strings.NewReader(string(jsonByte)))
	}
	return
}

func (s *Server) BaseCreateFashion(ctx context.Context, req *proto.BaseFashion) (ret *proto.BaseFashion, err error) {
	fashionTbl := fashion.NewModel(s.Pgsql.Get())
	ret, err = fashionTbl.Create(req)
	if err != nil {
		return
	}
	return
}

func (s *Server) BaseGetFashionList(ctx context.Context, req *proto.BaseGetFashionListReq) (ret *proto.BaseGetFashionListRes, err error) {
	req.Page--
	fashionTbl := fashion.NewModel(s.Pgsql.Get())
	ret, err = fashionTbl.GetList(req)
	if err != nil {
		common.Loger.Error("BaseGetFashionList err:%v", err)
		return
	}
	ret.PageSize = req.PageSize
	ret.Page = req.Page + 1
	return
}

func (s *Server) BaseGetFashionDetail(ctx context.Context, req *proto.BaseGetFashionDetailReq) (ret *proto.BaseGetFashionDetailRes, err error) {
	ret = new(proto.BaseGetFashionDetailRes)
	fashionTbl := fashion.NewModel(s.Pgsql.Get())
	ret.Fashion, err = fashionTbl.GetDetail(req.Id)
	if err != nil && err != sql.ErrNoRows {
		common.Loger.Error("BaseGetFashionDetail err:%v", err)
		return
	}
	cutpartTbl := cutpart.NewModel(s.Pgsql.Get())
	ret.BaseCutpartList, err = cutpartTbl.GetListByFashionId(req.Id)
	return
}

func (s *Server) GetCutpartList(ctx context.Context, req *proto.GetCutpartListReq) (ret *proto.BaseCutparts, err error) {
	ret = new(proto.BaseCutparts)
	cutpartTbl := cutpart.NewModel(s.Pgsql.Get())
	ret.BaseCutpartList, err = cutpartTbl.GetListByFashionId(req.FashionId)
	return
}

func (s *Server) BaseUpdateFashion(ctx context.Context, req *proto.BaseFashion) (ret *proto.BaseFashion, err error) {
	fashionTbl := fashion.NewModel(s.Pgsql.Get())
	ret, err = fashionTbl.Update(req)
	if err != nil {
		return
	}
	return
}

func (s *Server) BaseUpdateFashionItemObj(ctx context.Context, req *proto.BaseCutparts) (ret *proto.BaseNull, err error) {
	ret = new(proto.BaseNull)
	db := s.Pgsql.Get()
	tx, err := db.Begin()
	if err != nil {
		return
	}
	cutpartTbl := cutpart.NewTx(tx)
	err = cutpartTbl.DeleteByFashionId(req.FashionId)
	if err != nil {
		tx.Rollback()
		return
	}
	err = cutpartTbl.BatchCreate(req)
	if err != nil {
		tx.Rollback()
		return
	}
	fashionTbl := fashion.NewTx(tx)
	err = fashionTbl.UpdateObjUrl(req.FashionId, req.ObjUrl)
	if err != nil {
		tx.Rollback()
		return
	}
	err = tx.Commit()
	return
}

func (s *Server) BaseUpdateFashionDxf(ctx context.Context, req *proto.BaseFashion) (ret *proto.BaseNull, err error) {
	ret = new(proto.BaseNull)
	fashionTbl := fashion.NewModel(s.Pgsql.Get())
	//检测是否已有obj，如果有更新dxf_info
	fashionDetail, _ := s.BaseGetFashionDetail(ctx, &proto.BaseGetFashionDetailReq{Id: req.Id})
	newBorderPointUrl := ""
	if fashionDetail != nil && fashionDetail.Fashion != nil {
		if fashionDetail.Fashion.ObjUrl != "" {
			newBorderPointUrl, err = services.UpdateDxfInfo(req.Id, req.DxfUrl, fashionDetail.Fashion.ObjUrl, fashionDetail.Fashion.CutpartBorderPoint, fashionDetail.BaseCutpartList)
			if err != nil {
				return
			}
		}
	}
	if newBorderPointUrl != "" {
		err = fashionTbl.UpdateBorderPointUrlById(req.Id, newBorderPointUrl)
		if err != nil {
			return
		}
	}
	err = fashionTbl.UpdateDxfUrl(req.Id, req.DxfUrl)
	if err != nil {
		return
	}
	return
}

func (s *Server) BaseUpdateFashionAlgorithmParam(ctx context.Context, req *proto.BaseFashion) (ret *proto.BaseNull, err error) {
	ret = new(proto.BaseNull)
	fashionTbl := fashion.NewModel(s.Pgsql.Get())
	err = fashionTbl.UpdateAlgorithmParam(req)
	if err != nil {
		common.Loger.Error("BaseUpdateFashionAlgorithmParam err:%v", err)
		return
	}
	return
}

func (s *Server) BaseDeleteCutpart(ctx context.Context, req *proto.BaseCutpart) (ret *proto.BaseNull, err error) {
	ret = new(proto.BaseNull)
	tx, err := s.Pgsql.Get().Begin()
	if err != nil {
		return
	}
	cutpartTbl := cutpart.NewTx(tx)
	err = cutpartTbl.DeleteByIds(strings.Split(req.Id, ","))
	if err != nil {
		_ = tx.Rollback()
		return
	}
	err = tx.Commit()
	if err != nil {
		_ = tx.Rollback()
		return
	}
	return
}

func (s *Server) BaseGetCutpartDetail(ctx context.Context, req *proto.BaseCutpart) (ret *proto.BaseCutpart, err error) {
	cutpartTbl := cutpart.NewModel(s.Pgsql.Get())
	ret, err = cutpartTbl.GetById(req.Id)
	if err != nil {
		return
	}
	return
}

func (s *Server) BaseUpdateCutpart(ctx context.Context, req *proto.BaseCutpart) (ret *proto.BaseNull, err error) {
	ret = new(proto.BaseNull)
	cutpartTbl := cutpart.NewModel(s.Pgsql.Get())
	err = cutpartTbl.UpdateById(req)
	if err != nil {
		common.Loger.Error("BaseUpdateCutpart err:%v", err)
		return
	}
	return
}
